package com.liusand.movement.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.liusand.api.UserApi;
import com.liusand.common.utils.Base64Utils;
import com.liusand.common.utils.Utils;
import com.liusand.entity.dto.IdListDto;
import com.liusand.entity.dto.MovementDto;
import com.liusand.entity.pojo.Movement;
import com.liusand.entity.pojo.User;
import com.liusand.entity.vo.MovementVo;
import com.liusand.entity.vo.PageInfo;
import com.liusand.entity.vo.Result;
import com.liusand.movement.config.Oss;
import com.liusand.movement.mapper.MovementMapper;
import com.liusand.movement.service.MovementService;
import com.liusand.movement.thread.UserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author :liusha
 * packageName :com.liusand.movement.service.impl
 * fileName :MovementServiceImpl
 * creationTime :2022/12/23 15:44
 */
@Service
@Slf4j
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MovementMapper movementMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private Oss oss;

    @Autowired
    private UserApi userApi;

    @Override
    public boolean addMovement(MovementDto movementDto){
        if(movementDto == null){
            return false;
        }
        Movement movement = new Movement();
        BeanUtils.copyProperties(movementDto, movement);
        movement.setId(IdUtil.getSnowflakeNextIdStr());
        String userId = UserThreadLocalUtil.getId();
        movement.setUserId(userId);
        movement.setCreateTime(LocalDateTime.now());
        movement.setIsDeleted(0);
        List<String> fileUrl = new ArrayList<>();

        for(MultipartFile file : movementDto.getFiles()){
            if (file == null){
                continue;
            }
            UUID uuid = UUID.randomUUID();
            String contentType = file.getContentType();
            String fileName = contentType.substring(contentType.lastIndexOf("/") + 1);
            fileName = new SimpleDateFormat("yyyy/MM/dd").format(new Date())
                    + "/" + uuid + "." + fileName;

            Map<String, String> map = new HashMap<>();
            map.put("fileName", fileName);
            String fileBase64String;
            try {
                fileBase64String = Base64Utils.inputStream2Base64(file.getInputStream());
            }catch (Exception e){
                throw new RuntimeException(e);
            }
            map.put("file", fileBase64String);
            rabbitTemplate.convertAndSend("exchange.images","image", JSON.toJSONString(map, true));
            fileUrl.add(oss.getUrl() + "/" + fileName);

        }
        String images = String.join(",",fileUrl);
        log.info(images);
        movement.setImages(images);

        Integer movementResult = movementMapper.insertOne(movement);
        if (movementResult != 1){
            throw new RuntimeException("动态插入异常");
        }
        return true;
    }

    @Override
    public PageInfo<MovementVo> getMovement(Integer page, Integer pageSize) {
        //1.查询动态列表数据
        Integer start = (page - 1) * pageSize;
        List<MovementVo> movementList = movementMapper.selectAllOrderByCreateTime(start,pageSize);
        PageInfo<MovementVo> pageInfo = new PageInfo<>();
        pageInfo.setPageSize(pageSize);
        pageInfo.setCurrent(page);
        pageInfo.setTotal(0L);
        if(movementList == null){
            return pageInfo;
        }
        //2.查询动态列表中，每一条动态对应的用户信息
        //2.1.提取动态列表中每个用户的id
        Set<String> userIds = movementList.stream().filter(Objects::nonNull).map(MovementVo::getUserId).collect(Collectors.toSet());
        IdListDto idListDto = new IdListDto();
        idListDto.setIds(new ArrayList<>(userIds));
        //2.2.向用户服务发起请求，获取对应的用户信息
        Result userInfo = userApi.getUserInfo(idListDto);
        if(userInfo == null || userInfo.getCode() != 200){
            throw new RuntimeException("服务请求异常");
        }
//        List<User> userList = (List<User>) userInfo.getData();
        String userListString = (String) userInfo.getData();
        if(StringUtils.isEmpty(userListString)){
            throw new RuntimeException("类型转换异常");
        }
        List<User> userList = JSON.parseArray(userListString, User.class);
        if(userList == null){
            throw new RuntimeException("类型转换异常");
        }
        Map<String, User> map = userList.stream().filter(Objects::nonNull).collect(Collectors.toMap(User::getId, Function.identity()));
        //2.3.将请求回来的用户信息和动态信息进行组合
        for(MovementVo movementVo : movementList){
            User user = map.get(movementVo.getUserId());
            BeanUtils.copyProperties(user,movementVo);
            //3.处理几个特殊字段 年龄，配图，发布时间（xx分钟前），点赞数，评论数，喜欢数
            movementVo.setAge(Utils.birthday2age(user.getBirthday()));
            String imageString = movementVo.getImageString();
            movementVo.setImages(new ArrayList<>(List.of(imageString.split(","))));
            movementVo.setTime(Utils.timeConvert(movementVo.getCreateTime()));
        }
        //4.把满足当前条件的动态总数也查出来
        Long total = movementMapper.countMovement(start, pageSize);
        pageInfo.setTotal(total);
        pageInfo.setInfo(movementList);
        //5.组装成pageInfo返回
        return pageInfo;
    }
}
